from django.core.files.storage import Storage
from fdfs_client.client import Fdfs_client
from django.conf import settings


class FastDFSStorage(Storage):
    """自定义文件存储系统"""

    def __init__(self, client_conf=None, base_url=None):
        """初始化方法"""
        # self.client_conf = client_conf
        # if client_conf:
        #     self.client_conf = client_conf
        # else:
        #     self.client_conf = settings.FDFS_CLIENT_CONF

        # if,else简写为三目运算符
        # self.client_conf = client_conf if client_conf else settings.FDFS_CLIENT_CONF
        self.client_conf = client_conf or settings.FDFS_CLIENT_CONF
        self.base_url = base_url or settings.FDFS_URL

    def _open(self, name, mode='rb'):
        """
        打开storage中上传的文件,我们只是为了上传文件本不需要打开,但是官方要求必须重写
        :param name: 表示要打开的文件名
        :param mode: 表示打开文件的模式 read bytes
        """
        pass

    def _save(self, name, content):
        """
        当保存时就会调用此方法
        :param name: 要保存的文件名
        :param content: 要保存的文件对象
        :return: file_id 把上传后的文件路径返回
        """
        # 1.创建client
        # client = Fdfs_client('meiduo_mall/utils/fastdfs/client.conf')
        client = Fdfs_client(self.client_conf)
        # 2.上传文件到fastdfs
        # 此方法只支持本地绝对路径来上传,上传的文件在storage中有后缀
        # ret = client.upload_appender_by_filename('路径')
        # 把要上传的文件二进制传入,进行上传,上传的图片没有后缀
        ret = client.upload_appender_by_buffer(content.read())

        # 3.判断上传是否成功
        if ret.get('Status') != 'Upload successed.':
            raise Exception('Upload files failed')

        # 4.执行到这儿说明上传成功
        return ret.get('Remote file_id')

    def exists(self, name):
        """
        如果返回True,表示要上传的文件已经存在,就不会再上传,如果返回False,表示当前要上传的文件不存在,可以上传
        :param name: 要上传的文件名
        :return: 此方法只返回bool值
        """
        return False

    def url(self, name):
        """
        返回上传到fastdfs中路径的绝对路径给浏览器访问使用
        :param name: 就是上传到fastdfs中的file_id
        :return:
        """
        return self.base_url + name